package com.dsjy.yf.address.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dsjy.yf.address.config.base.BizException;
import com.dsjy.yf.address.config.base.CommonEnum;
import com.dsjy.yf.address.entity.myenum.TableEnum;
import com.dsjy.yf.address.entity.query.AdminDeleteQuery;
import com.dsjy.yf.address.entity.query.PageSearchQuery;
import com.dsjy.yf.address.entity.query.SearchQuery;
import com.dsjy.yf.address.mapper.*;
import com.dsjy.yf.address.service.*;
import com.dsjy.yf.address.utils.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author whj
 * @version 1.0
 * @date 2021-01-20 9:06
 */
@Service
public class CommonServiceImpl implements CommonService {
    @Autowired
    private UserUtil userUtil;

    @Autowired
    private CountyService countyService;
    @Autowired
    private ExclusivezoneService exclusivezoneService;
    @Autowired
    private TownService townService;
    @Autowired
    private CommunityService communityService;
    @Autowired
    private VillageService villageService;
    @Autowired
    private StreetService streetService;
    @Autowired
    private BuildingService buildingService;
    @Autowired
    private YardService yardService;
    @Autowired
    private YardRoadService yardRoadService;
    @Autowired
    private SubareaService subareaService;
    @Autowired
    private PoiService poiService;

    @Resource
    private CommonMapper commonMapper;

    @Resource
    private CountyMapper countyMapper;
    @Resource
    private ExclusivezoneMapper exclusivezoneMapper;
    @Resource
    private TownMapper townMapper;
    @Resource
    private CommunityMapper communityMapper;
    @Resource
    private VillageMapper villageMapper;
    @Resource
    private StreetMapper streetMapper;
    @Resource
    private BuildingMapper buildingMapper;
    @Resource
    private YardMapper yardMapper;
    @Resource
    private YardRoadMapper yardRoadMapper;
    @Resource
    private SubareaMapper subareaMapper;
    @Resource
    private PoiMapper poiMapper;


    @Override
    public Object searchWithCode(Integer parentCode, String tableName) {
        if (TableEnum.EXCLUSIVEZONE.getTableName().equals(tableName)) {
            return exclusivezoneService.searchExclusivezoneWithParentCode(parentCode, false);
        } else if (TableEnum.POI.getTableName().equals(tableName)) {
            return poiService.searchPoiWithParentCode(parentCode, false);
        } else if (TableEnum.TOWN.getTableName().equals(tableName)) {
            return townService.searchByCountyCode(parentCode);
        } else if (TableEnum.COMMUNITY.getTableName().equals(tableName)) {
            return communityService.searchWithTownCode(parentCode, false);
        } else if (TableEnum.VILLAGE.getTableName().equals(tableName)) {
            return villageService.searchVillageWithParentCode(parentCode, false);
        } else if (TableEnum.STREET.getTableName().equals(tableName)) {
            return streetService.searchStreetWithParentCode(parentCode, false);
        } else if (TableEnum.BUILDING.getTableName().equals(tableName)) {
            return buildingService.searchBuildingWithCode(parentCode, false);
        } else if (TableEnum.YARD.getTableName().equals(tableName)) {
            return yardService.searchYardWithCode(parentCode, false);
        } else if (TableEnum.YARDROAD.getTableName().equals(tableName)) {
            return yardRoadService.searchYardRoadWithParentCode(parentCode, false);
        } else if (TableEnum.SUBAREA.getTableName().equals(tableName)) {
            return subareaService.searchSubareaWithParentCode(parentCode, false);
        }
        return null;
    }

    @Override
    public Object searchWithPage(PageSearchQuery pageSearchQuery, Boolean isAdmin) {
        QueryWrapper<Object> wrapper = new QueryWrapper<>();
        wrapper.eq("deleted", isAdmin);
        Integer pageNum = pageSearchQuery.getPageNum();
        Integer pageSize = pageSearchQuery.getPageSize();
        IPage page = null;
        boolean nameQuery = !pageSearchQuery.queryIsNull();
        String name = pageSearchQuery.getQuery();
        if (TableEnum.COUNTY.getTableName().equals(pageSearchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.COUNTY.getFieldName(), name);
            }
            page = countyService.searchWithPage(pageNum, pageSize, isAdmin, wrapper);
        } else if (TableEnum.EXCLUSIVEZONE.getTableName().equals(pageSearchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.EXCLUSIVEZONE.getFieldName(), name);
            }
            page = exclusivezoneService.searchWithPage(pageNum, pageSize, wrapper);
        } else if (TableEnum.POI.getTableName().equals(pageSearchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.POI.getFieldName(), name);
            }
            page = poiService.searchWithPage(pageNum, pageSize, wrapper);
        } else if (TableEnum.TOWN.getTableName().equals(pageSearchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.TOWN.getFieldName(), name);
            }
            page = townService.searchWithPage(pageNum, pageSize, wrapper);
        } else if (TableEnum.COMMUNITY.getTableName().equals(pageSearchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.COMMUNITY.getFieldName(), name);
            }
            page = communityService.searchWithPage(pageNum, pageSize, wrapper);
        } else if (TableEnum.VILLAGE.getTableName().equals(pageSearchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.VILLAGE.getFieldName(), name);
            }
            page = villageService.searchWithPage(pageNum, pageSize, wrapper);
        } else if (TableEnum.STREET.getTableName().equals(pageSearchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.STREET.getFieldName(), name);
            }
            page = streetService.searchWithPage(pageNum, pageSize, wrapper);
        } else if (TableEnum.BUILDING.getTableName().equals(pageSearchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.BUILDING.getFieldName(), name);
            }
            page = buildingService.searchWithPage(pageNum, pageSize, wrapper);
        } else if (TableEnum.YARD.getTableName().equals(pageSearchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.YARD.getFieldName(), name);
            }
            page = yardService.searchWithPage(pageNum, pageSize, wrapper);
        } else if (TableEnum.YARDROAD.getTableName().equals(pageSearchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.YARDROAD.getFieldName(), name);
            }
            page = yardRoadService.searchWithPage(pageNum, pageSize, wrapper);
        } else if (TableEnum.SUBAREA.getTableName().equals(pageSearchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.SUBAREA.getFieldName(), name);
            }
            page = subareaService.searchWithPage(pageNum, pageSize, wrapper);
        }
        if (page != null) {
            Map<String, Object> map = new HashMap<>(3);
            map.put("total", page.getTotal());
            map.put("pages", page.getPages());
            map.put("records", page.getRecords());
            return map;
        } else {
            throw new BizException(CommonEnum.PARAM_ERROR);
        }
    }

    @Override
    public Object searchWithQuery(SearchQuery searchQuery, Boolean isAdmin) {
        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.eq("deleted", isAdmin);
        Integer parentCode = searchQuery.getParentCode();
        if (parentCode != null) {
            wrapper.eq("parent_code", parentCode);
        }
        boolean nameQuery = searchQuery.queryIsNotNull();
        String name = searchQuery.getQuery();
        List list = null;
        if (TableEnum.COUNTY.getTableName().equals(searchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.COUNTY.getFieldName(), name);
            }
            list = countyMapper.selectList(wrapper);
        } else if (TableEnum.EXCLUSIVEZONE.getTableName().equals(searchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.EXCLUSIVEZONE.getFieldName(), name);
            }
            list = exclusivezoneMapper.selectList(wrapper);
        } else if (TableEnum.POI.getTableName().equals(searchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.POI.getFieldName(), name);
            }
            list = poiMapper.selectList(wrapper);
        } else if (TableEnum.TOWN.getTableName().equals(searchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.TOWN.getFieldName(), name);
            }
            list = townMapper.selectList(wrapper);
        } else if (TableEnum.COMMUNITY.getTableName().equals(searchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.COMMUNITY.getFieldName(), name);
            }
            list = communityMapper.selectList(wrapper);
        } else if (TableEnum.VILLAGE.getTableName().equals(searchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.VILLAGE.getFieldName(), name);
            }
            list = villageMapper.selectList(wrapper);
        } else if (TableEnum.STREET.getTableName().equals(searchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.STREET.getFieldName(), name);
            }
            list = streetMapper.selectList(wrapper);
        } else if (TableEnum.BUILDING.getTableName().equals(searchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.BUILDING.getFieldName(), name);
            }
            list = buildingMapper.selectList(wrapper);
        } else if (TableEnum.YARD.getTableName().equals(searchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.YARD.getFieldName(), name);
            }
            list = yardMapper.selectList(wrapper);
        } else if (TableEnum.YARDROAD.getTableName().equals(searchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.YARDROAD.getFieldName(), name);
            }
            list = yardRoadMapper.selectList(wrapper);
        } else if (TableEnum.SUBAREA.getTableName().equals(searchQuery.getTableName())) {
            if (nameQuery) {
                wrapper.like(TableEnum.SUBAREA.getFieldName(), name);
            }
            list = subareaMapper.selectList(wrapper);
        }
        if (list != null) {
            Map<String, Object> map = new HashMap<>(2);
            map.put("total", list.size());
            map.put("records", list);
            return map;
        } else {
            throw new BizException(CommonEnum.PARAM_ERROR);
        }
    }

    @Override
    @Caching(evict = {
            @CacheEvict(value = "county", condition = "'county' eq #query.tableName", allEntries = true),
            @CacheEvict(value = "exclusivezone", condition = "'exclusivezone' eq #query.tableName ", allEntries = true),
            @CacheEvict(value = "poi", condition = "'poi' eq #query.tableName ", allEntries = true),
            @CacheEvict(value = "town", condition = "'town' eq #query.tableName ", allEntries = true),
            @CacheEvict(value = "community", condition = "'community' eq #query.tableName ", allEntries = true),
            @CacheEvict(value = "village", condition = "'village' eq #query.tableName ", allEntries = true),
            @CacheEvict(value = "street", condition = "'street' eq #query.tableName ", allEntries = true),
            @CacheEvict(value = "building", condition = "'building' eq #query.tableName ", allEntries = true),
            @CacheEvict(value = "yard", condition = "'yard' eq #query.tableName ", allEntries = true),
            @CacheEvict(value = "yardroad", condition = "'yardroad' eq #query.tableName ", allEntries = true),
            @CacheEvict(value = "subarea", condition = "'subarea' eq #query.tableName ", allEntries = true)
    })
    public Integer deleteById(AdminDeleteQuery query) {
        if (query.isNotNull() && query.nameIsSafe()) {
            if (query.getIsDelete()) {
                return commonMapper.deleteById(query.getTableName(), query.getId());
            } else {
                return commonMapper.fakeDelete(query.getTableName(), query.getId(), false);
            }
        } else {
            throw new BizException(CommonEnum.PARAM_ERROR);
        }
    }

    @Override
    @Caching(evict = {
            @CacheEvict(value = "county", condition = "'county' eq #tableName ", allEntries = true),
            @CacheEvict(value = "exclusivezone", condition = "'exclusivezone' eq #tableName ", allEntries = true),
            @CacheEvict(value = "poi", condition = "'poi' eq #tableName ", allEntries = true),
            @CacheEvict(value = "town", condition = "'town' eq #tableName ", allEntries = true),
            @CacheEvict(value = "community", condition = "'community' eq #tableName ", allEntries = true),
            @CacheEvict(value = "village", condition = "'village' eq #tableName ", allEntries = true),
            @CacheEvict(value = "street", condition = "'street' eq #tableName ", allEntries = true),
            @CacheEvict(value = "building", condition = "'building' eq #tableName ", allEntries = true),
            @CacheEvict(value = "yard", condition = "'yard' eq #tableName ", allEntries = true)
            //@CacheEvict(value = "yardroad", condition = "'yardroad' eq #tableName ", allEntries = true),
            //@CacheEvict(value = "subarea", condition = "'subarea' eq #tableName ", allEntries = true)
    })
    public Integer deleteById(String tableName, Integer id) {
        if (id == null) {
            throw new BizException(CommonEnum.PARAM_ERROR);
        }
        if (userUtil.isAdmin()) {
            return commonMapper.deleteById(tableName, id);
        } else {
            return commonMapper.fakeDelete(tableName, id, true);
        }
    }
}
